package com.hxh.essaysharing.controller;

import com.hxh.essaysharing.common.AjaxResult;
import com.hxh.essaysharing.common.ApplicationVariable;
import com.hxh.essaysharing.common.MarkdownUtils;
import com.hxh.essaysharing.common.UserSessionUtils;
import com.hxh.essaysharing.entity.Articleinfo;
import com.hxh.essaysharing.entity.Userinfo;
import com.hxh.essaysharing.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 * @date 2023/7/22 19:49
 */
@RestController
@RequestMapping("/art")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    /**
     * 加载用户的文章列表信息
     * key: 搜索 title
     * state: 0 草稿, 1 文章
     */
    @RequestMapping("/mylist")
    public AjaxResult getMyList(HttpServletRequest request, Integer state, String key) {
        Userinfo userinfo = UserSessionUtils.getSessUser(request);
        if (userinfo == null) {
            return AjaxResult.fail(-1, "非法请求");
        }
        List<Articleinfo> list = articleService.getMyList(userinfo.getId(), state, key);
        // 将 list 中每个文章信息对象的正文进行处理, 去除 markdown 标签并最多显示 256 个字符
        for (Articleinfo articleinfo : list) {
            String content = articleinfo.getContent();
            content = MarkdownUtils.removeMarkdownTags(content,
                    ApplicationVariable.THE_MAXIMUM_NUMBER_OF_CHARACTERS_IN_THE_DIGEST);
            articleinfo.setContent(content);
        }
        return AjaxResult.success(list);
    }

    /**
     * 删除文章
     * 只有当前登录的用户是文章的作者才能删除(验权)
     */
    @RequestMapping("/del")
    public AjaxResult del(HttpServletRequest request, @RequestParam("aid") Integer id) {
        // 参数检验
        if (id == null || id <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        // 进行删除
        // 只有当前登录的用户同时是文章的作者的情况下才能删除
        Userinfo user = UserSessionUtils.getSessUser(request);
        if (user == null) {
            return AjaxResult.fail(-2, "用户未登录");
        }
        int delCount = articleService.del(id, user.getId());
        return AjaxResult.success(delCount);
    }

    /**
     * 获取文章详细信息
     */
    @RequestMapping("/detail")
    public AjaxResult getDetail(Integer id) {
        if (id == null || id <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        return AjaxResult.success(articleService.getDetail(id));
    }

    /**
     * 阅读量 + 1
     */
    @RequestMapping("/updatercount")
    public AjaxResult updateRCount(Integer id) {
        if (id == null || id <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        return AjaxResult.success(articleService.updateRCount(id));
    }

    /**
     * 发布文章 state = 1 与保存草稿箱 state = 0
     * 如果是保存草稿箱, 则请求的文章对象中 state = 0
     * 更新了传入 createtime 和 updatetime 解决数据库不兼容问题
     */
    @RequestMapping("/add")
    public AjaxResult add(HttpServletRequest request, Articleinfo articleinfo) {
        // 非空校验
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle()) ||
                !StringUtils.hasLength(articleinfo.getContent())) {
            return AjaxResult.fail(-1, "非法参数");
        }
        // 发布文章操作
        // 得到当前用户的 uid
        Userinfo userinfo = UserSessionUtils.getSessUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            // 无效的登录用户
            return AjaxResult.fail(-2, "无效的登录用户");
        }
        articleinfo.setUid(userinfo.getId()); // 设置作者 id
        // 设置创建时间和更新时间, 解决数据库没有默认约束的情况
        articleinfo.setCreatetime(LocalDateTime.now());
        articleinfo.setUpdatetime(LocalDateTime.now());
        // 添加数据库并返回
        return AjaxResult.success(articleService.add(articleinfo));
    }

    /**
     * 修改文章
     * 只有当前登录用户是作者的情况下才能进行修改(验权)
     */
    @RequestMapping("/update")
    public AjaxResult update(HttpServletRequest request, Articleinfo articleinfo) {
        // 非空检验
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle()) ||
                !StringUtils.hasLength(articleinfo.getContent()) ||
                articleinfo.getId() == null ||
                articleinfo.getId() <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        // 得到当前登录用户的 id
        Userinfo userinfo = UserSessionUtils.getSessUser(request);
        if (userinfo == null || userinfo.getId() == null || userinfo.getId() <= 0) {
            return AjaxResult.fail(-2, "无效用户");
        }
        // 设置文章对象的 uid 为当前用户的 id, 便于 mapper 验证是否为当前登录用户
        articleinfo.setUid(userinfo.getId());
        articleinfo.setUpdatetime(LocalDateTime.now());
        return AjaxResult.success(articleService.update(articleinfo));
    }

    /**
     * 分页查询
     * @param pIndex 当前页码
     * @param pSize  每页最多显示的文章条数
     * @param key  检索的 title
     * @return  返回的 data 中包含一个 map, 含有当前页的文章列表与文章总数量
     */
    @RequestMapping("/listbypage")
    public AjaxResult getListByPage(@RequestParam("pindex") Integer pIndex,
                                    @RequestParam("psize") Integer pSize,
                                    @RequestParam("key") String key) {
        // 参数校正
        if (pIndex == null || pIndex < 1) {
            pIndex = 1;
        }
        if (pSize == null || pSize <= 1) {
            pSize = 3;
        }
        // 分页查询
        int offSize = (pIndex - 1) * pSize;
        List<Articleinfo> articleInfoList = articleService.getListByPage(pSize, offSize, key);
        // 对摘要进行处理
        for (Articleinfo articleinfo : articleInfoList) {
            articleinfo.setContent(
                    MarkdownUtils.removeMarkdownTags(articleinfo.getContent(), 256));
        }
        // 获取文章总数
        int totalArticleCount = articleService.getTotalArticleCount(key);
        HashMap<String, Object> map = new HashMap<>();
        map.put("articleInfoList", articleInfoList);
        map.put("totalArticleCount", totalArticleCount);
        return AjaxResult.success(map);
    }
}
